'use strict';
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
const u = require('./nodes/identity.cjs'),
  a = Symbol('break visit'),
  j = Symbol('skip children'),
  i = Symbol('remove node');
function m(e, l) {
  const c = P(l);
  u.isDocument(e)
    ? r(null, e.contents, c, Object.freeze([e])) === i && (e.contents = null)
    : r(null, e, c, Object.freeze([]));
}
m.BREAK = a;
m.SKIP = j;
m.REMOVE = i;
function r(e, l, c, n) {
  const t = A(e, l, c, n);
  if (u.isNode(t) || u.isPair(t)) return E(e, n, t), r(e, t, c, n);
  if (typeof t != 'symbol') {
    if (u.isCollection(l)) {
      n = Object.freeze(n.concat(l));
      for (let f = 0; f < l.items.length; ++f) {
        const s = r(f, l.items[f], c, n);
        if (typeof s == 'number') f = s - 1;
        else {
          if (s === a) return a;
          s === i && (l.items.splice(f, 1), (f -= 1));
        }
      }
    } else if (u.isPair(l)) {
      n = Object.freeze(n.concat(l));
      const f = r('key', l.key, c, n);
      if (f === a) return a;
      f === i && (l.key = null);
      const s = r('value', l.value, c, n);
      if (s === a) return a;
      s === i && (l.value = null);
    }
  }
  return t;
}
async function y(e, l) {
  const c = P(l);
  u.isDocument(e)
    ? (await b(null, e.contents, c, Object.freeze([e]))) === i &&
      (e.contents = null)
    : await b(null, e, c, Object.freeze([]));
}
y.BREAK = a;
y.SKIP = j;
y.REMOVE = i;
async function b(e, l, c, n) {
  const t = await A(e, l, c, n);
  if (u.isNode(t) || u.isPair(t)) return E(e, n, t), b(e, t, c, n);
  if (typeof t != 'symbol') {
    if (u.isCollection(l)) {
      n = Object.freeze(n.concat(l));
      for (let f = 0; f < l.items.length; ++f) {
        const s = await b(f, l.items[f], c, n);
        if (typeof s == 'number') f = s - 1;
        else {
          if (s === a) return a;
          s === i && (l.items.splice(f, 1), (f -= 1));
        }
      }
    } else if (u.isPair(l)) {
      n = Object.freeze(n.concat(l));
      const f = await b('key', l.key, c, n);
      if (f === a) return a;
      f === i && (l.key = null);
      const s = await b('value', l.value, c, n);
      if (s === a) return a;
      s === i && (l.value = null);
    }
  }
  return t;
}
function P(e) {
  return typeof e == 'object' && (e.Collection || e.Node || e.Value)
    ? Object.assign(
        { Alias: e.Node, Map: e.Node, Scalar: e.Node, Seq: e.Node },
        e.Value && { Map: e.Value, Scalar: e.Value, Seq: e.Value },
        e.Collection && { Map: e.Collection, Seq: e.Collection },
        e,
      )
    : e;
}
function A(e, l, c, n) {
  var t, f, s, S, O;
  if (typeof c == 'function') return c(e, l, n);
  if (u.isMap(l)) return (t = c.Map) == null ? void 0 : t.call(c, e, l, n);
  if (u.isSeq(l)) return (f = c.Seq) == null ? void 0 : f.call(c, e, l, n);
  if (u.isPair(l)) return (s = c.Pair) == null ? void 0 : s.call(c, e, l, n);
  if (u.isScalar(l))
    return (S = c.Scalar) == null ? void 0 : S.call(c, e, l, n);
  if (u.isAlias(l)) return (O = c.Alias) == null ? void 0 : O.call(c, e, l, n);
}
function E(e, l, c) {
  const n = l[l.length - 1];
  if (u.isCollection(n)) n.items[e] = c;
  else if (u.isPair(n)) e === 'key' ? (n.key = c) : (n.value = c);
  else if (u.isDocument(n)) n.contents = c;
  else {
    const t = u.isAlias(n) ? 'alias' : 'scalar';
    throw new Error(`Cannot replace node with ${t} parent`);
  }
}
exports.visit = m;
exports.visitAsync = y;
